{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ABU量化系统使用文档 \n",
    "\n",
    "<center>\n",
    "        <img src=\"./image/abu_logo.png\" alt=\"\" style=\"vertical-align:middle;padding:10px 20px;\"><font size=\"6\" color=\"black\"><b>第18节 自定义裁判决策交易</b></font>\n",
    "</center>\n",
    "\n",
    "-----------------\n",
    "\n",
    "作者: 阿布\n",
    "\n",
    "阿布量化版权所有 未经允许 禁止转载\n",
    "\n",
    "[abu量化系统github地址](https://github.com/bbfamily/abu) (欢迎+star)\n",
    "\n",
    "[本节ipython notebook](https://github.com/bbfamily/abu/tree/master/abupy_lecture)\n",
    "\n",
    "上一节示例了ump边裁的使用以及回测示例，最后说过对决策效果提升最为重要的是：训练更多交易数据，更多策略来提升裁判的拦截水平及拦截认知范围，给每一个裁判看更多的比赛录像（回测数据），提高比赛录像水准，从多个不同视角录制比赛(回测交易)，扩展裁判。\n",
    "\n",
    "对于ump模块每个裁判类有自己关心的交易特征，使用特定的特征做为决策依据，即：每个裁判有自己在比赛中所特定关心的视角或者行为，之前的章节讲解的都是abupy内置裁判的使用示例，本节将讲解示例自定义裁判，通过不同的视角录制比赛。\n",
    "\n",
    "对于训练更多交易数据，更多策略来提升裁判的拦截水平及拦截认知范围请阅读《量化交易之路》中的相关全市场回测。\n",
    "\n",
    "首先导入abupy中本节使用的模块："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "enable example env will only read RomDataBu/df_kl.h5\n"
     ]
    }
   ],
   "source": [
    "# 基础库导入\n",
    "\n",
    "from __future__ import print_function\n",
    "from __future__ import division\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "import os\n",
    "import sys\n",
    "# 使用insert 0即只使用github，避免交叉使用了pip安装的abupy，导致的版本不一致问题\n",
    "sys.path.insert(0, os.path.abspath('../'))\n",
    "import abupy\n",
    "\n",
    "# 使用沙盒数据，目的是和书中一样的数据环境\n",
    "abupy.env.enable_example_env_ipython()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from abupy import AbuFactorAtrNStop, AbuFactorPreAtrNStop, AbuFactorCloseAtrNStop, AbuFactorBuyBreak, ABuProgress\n",
    "from abupy import abu, EMarketTargetType, AbuMetricsBase, ABuMarketDrawing, AbuFuturesCn, ABuSymbolPd, AbuOrderPdProxy\n",
    "from abupy import AbuUmpMainDeg, AbuUmpMainJump, AbuUmpMainPrice, AbuUmpMainWave, AbuFuturesCn, EStoreAbu, AbuML\n",
    "from abupy import AbuUmpEdgeDeg, AbuUmpEdgePrice, AbuUmpEdgeWave, AbuUmpEdgeFull\n",
    "from abupy import AbuMLPd, AbuUmpMainBase, AbuUmpEdgeBase, BuyUmpMixin, ump\n",
    "from abupy import feature, AbuFeatureBase, BuyFeatureMixin, SellFeatureMixin, ABuRegUtil"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与之前章节一样，本节示例的相关性分析只限制在abupy内置沙盒数据中，和上一节一样首先将内置沙盒中美股，A股，港股, 比特币，莱特币，期货市场中的symbol都列出来，然后组成训练集和测试集，买入卖出因子等相同设置:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS']\n",
    "cn_choice_symbols = ['002230', '300104', '300059', '601766', '600085', '600036', '600809', '000002', '002594']\n",
    "hk_choice_symbols = ['hk03333', 'hk00700', 'hk02333', 'hk01359', 'hk00656', 'hk03888', 'hk02318']\n",
    "tc_choice_symbols = ['btc', 'ltc']\n",
    "# 期货市场的直接从AbuFuturesCn().symbo中读取\n",
    "ft_choice_symbols = AbuFuturesCn().symbol.tolist()\n",
    "\n",
    "# 训练集：沙盒中所有美股 ＋ 沙盒中所有A股 ＋ 沙盒中所有港股 ＋ 比特币\n",
    "train_choice_symbols = us_choice_symbols + cn_choice_symbols +  hk_choice_symbols + tc_choice_symbols[:1]\n",
    "# 测试集：沙盒中所有期货 ＋ 莱特币\n",
    "test_choice_symbols = ft_choice_symbols  + tc_choice_symbols[1:]\n",
    "\n",
    "# 设置初始资金数\n",
    "read_cash = 1000000\n",
    "# 买入因子依然延用向上突破因子\n",
    "buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},\n",
    "               {'xd': 42, 'class': AbuFactorBuyBreak}]\n",
    "\n",
    "# 卖出因子继续使用上一节使用的因子\n",
    "sell_factors = [\n",
    "    {'stop_loss_n': 1.0, 'stop_win_n': 3.0,\n",
    "     'class': AbuFactorAtrNStop},\n",
    "    {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},\n",
    "    {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}\n",
    "]\n",
    "# 回测生成买入时刻特征\n",
    "abupy.env.g_enable_ml_feature = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "使用load_abu_result_tuple读取第15节中保存在本地的训练集数据："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:196\n",
      "胜率:59.6939%\n",
      "平均获利期望:18.6899%\n",
      "平均亏损期望:-7.1235%\n",
      "盈亏比:4.4972\n",
      "所有交易收益比例和:16.2396 \n",
      "所有交易总盈亏和:2717948.4900 \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "please wait! load_pickle....: /Users/Bailey/abu/data/cache/n2_lecture_train_capital\n",
      "please wait! load_pickle....: /Users/Bailey/abu/data/cache/n2_lecture_train_benchmark\n"
     ]
    }
   ],
   "source": [
    "abu_result_tuple_train = abu.load_abu_result_tuple(n_folds=2, store_type=EStoreAbu.E_STORE_CUSTOM_NAME, \n",
    "                                                   custom_name='lecture_train')\n",
    "orders_pd_train = abu_result_tuple_train.orders_pd\n",
    "AbuMetricsBase.show_general(*abu_result_tuple_train, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. 从不同视角训练新的主裁\n",
    "\n",
    "如下示例编写如何从不同视角组成裁判AbuUmpMainMul，其关心的视角为短线21天趋势角度，长线一年的价格rank，长线波动，以及atr波动如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuUmpMainMul(AbuUmpMainBase, BuyUmpMixin):\n",
    "    \"\"\"从不同视角训练新的主裁示例，AbuUmpMainBase子类，混入BuyUmpMixin，做为买入ump类\"\"\"\n",
    "\n",
    "    class UmpMulFiter(AbuMLPd):\n",
    "        @ump.ump_main_make_xy\n",
    "        def make_xy(self, **kwarg):\n",
    "            # regex='result|buy_deg_ang21|buy_price_rank252|buy_wave_score3|buy_atr_std'\n",
    "            regex = 'result|{}|{}|{}|{}'.format(feature.AbuFeatureDeg().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                                                feature.AbuFeaturePrice().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                                                feature.AbuFeatureWave().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                                                feature.AbuFeatureAtr().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1])\n",
    "            # noinspection PyUnresolvedReferences\n",
    "            mul_df = self.order_has_ret.filter(regex=regex)\n",
    "            return mul_df\n",
    "\n",
    "    def get_predict_col(self):\n",
    "        \"\"\"\n",
    "        主裁单混特征keys：['buy_deg_ang21', 'buy_price_rank252', 'buy_wave_score3', 'buy_atr_std']\n",
    "        :return: ['buy_deg_ang21', 'buy_price_rank252', 'buy_wave_score3', 'buy_atr_std']\n",
    "        \"\"\"\n",
    "\n",
    "        return [feature.AbuFeatureDeg().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                feature.AbuFeaturePrice().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                feature.AbuFeatureWave().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1],\n",
    "                feature.AbuFeatureAtr().get_feature_ump_keys(ump_cls=AbuUmpMainMul)[-1]]\n",
    "\n",
    "    def get_fiter_class(self):\n",
    "        \"\"\"\n",
    "        主裁单混特征返回的AbuMLPd子类：AbuUmpMainMul.UmpMulFiter\n",
    "        :return: AbuUmpMainMul.UmpMulFiter\n",
    "        \"\"\"\n",
    "        return AbuUmpMainMul.UmpMulFiter\n",
    "\n",
    "    @classmethod\n",
    "    def class_unique_id(cls):\n",
    "        \"\"\"\n",
    "        具体ump类关键字唯一名称，类方法：return 'mul_main'\n",
    "        主要针对外部user设置自定义ump使用, 需要user自己保证class_unique_id的唯一性，内部不做检测\n",
    "        具体使用见ABuUmpManager中extend_ump_block方法\n",
    "        \"\"\"\n",
    "        return 'mul_main'\n",
    "\n",
    "# 通过import的方式导入AbuUmpMainMul, 因为在windows系统上，启动并行后，在ipython notebook中定义的类会在子进程中无法找到\n",
    "from abupy import AbuUmpMainMul"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上所示，即完成一个全新ump主裁的编写：\n",
    "\n",
    "1. ump主裁需要继承AbuUmpMainBase，买入ump需要混入BuyUmpMixin\n",
    "2. 编写内部类继承自AbuMLPd，实现make_xy，即从训练集数据中筛选自己关心的特征\n",
    "3. 实现get_predict_col，返回关心的特征字符串名称\n",
    "4. 实现get_fiter_class，返回继承自AbuMLPd的内部类\n",
    "5. 实现class_unique_id，为裁判起一个唯一的名称\n",
    "\n",
    "备注：feature.AbuFeatureDeg()等为abupy中内置的特征类，稍后会讲解自定义特征类\n",
    "\n",
    "现在有了新的裁判AbuUmpMainMul，接下使用相同的训练集开始训练裁判，和第16节一样使用ump_main_clf_dump："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "please wait! dump_pickle....: /Users/Bailey/abu/data/ump/ump_main_umpmulfiter\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>result</th>\n",
       "      <th>buy_deg_ang21</th>\n",
       "      <th>buy_price_rank252</th>\n",
       "      <th>buy_wave_score3</th>\n",
       "      <th>buy_atr_std</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>1</td>\n",
       "      <td>2.255</td>\n",
       "      <td>0.857</td>\n",
       "      <td>0.441</td>\n",
       "      <td>1.159</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>0</td>\n",
       "      <td>1.837</td>\n",
       "      <td>0.798</td>\n",
       "      <td>-0.001</td>\n",
       "      <td>1.281</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>1</td>\n",
       "      <td>2.357</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.232</td>\n",
       "      <td>2.033</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>1</td>\n",
       "      <td>0.931</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.289</td>\n",
       "      <td>0.192</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>1</td>\n",
       "      <td>0.931</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.289</td>\n",
       "      <td>0.192</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            result  buy_deg_ang21  buy_price_rank252  buy_wave_score3  \\\n",
       "2014-09-25       1          2.255              0.857            0.441   \n",
       "2014-10-09       0          1.837              0.798           -0.001   \n",
       "2014-10-17       1          2.357              1.000            0.232   \n",
       "2014-10-24       1          0.931              1.000            1.289   \n",
       "2014-10-24       1          0.931              1.000            1.289   \n",
       "\n",
       "            buy_atr_std  \n",
       "2014-09-25        1.159  \n",
       "2014-10-09        1.281  \n",
       "2014-10-17        2.033  \n",
       "2014-10-24        0.192  \n",
       "2014-10-24        0.192  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ump_mul = AbuUmpMainMul.ump_main_clf_dump(orders_pd_train, p_ncs=slice(20, 40, 1))\n",
    "ump_mul.fiter.df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "显示的特征为四个特征即为新的主裁AbuUmpMainMul所关心的决策视角和行为。\n",
    "\n",
    "下面示例如何使用自定义裁判，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 把新的裁判AbuUmpMainMul类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpMainMul)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "即添加新的裁到系统中流程为：\n",
    "\n",
    "1. 打开使用用户自定义裁判开关：ump.manager.g_enable_user_ump = True\n",
    "2. 把新的裁判AbuUmpMainMul类名称使用append_user_ump添加到系统中，或者直接将上面训练好的对象ump_mul添加也可以\n",
    "\n",
    "备注：使用append_user_ump添加的裁判参数可以是类名称，也可以是类对象，但裁判必须是使用ump_main_clf_dump训练好的。\n",
    "\n",
    "下面使用新的裁判AbuUmpMainMul对测试集交易进行回测，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "abu_result_tuple_test_ump_main_user, _ = abu.run_loop_back(read_cash,\n",
    "                                                   buy_factors,\n",
    "                                                   sell_factors,\n",
    "                                                   start='2014-07-26',\n",
    "                                                   end='2016-07-26',\n",
    "                                                   choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:216\n",
      "胜率:41.6667%\n",
      "平均获利期望:9.2565%\n",
      "平均亏损期望:-5.0211%\n",
      "盈亏比:1.2766\n",
      "所有交易收益比例和:2.0042 \n",
      "所有交易总盈亏和:281522.2700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_main_user, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "使用测试集不使用任何主裁拦截情况下进行回测度量对比，如下所示:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 关闭用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = False\n",
    "abu_result_tuple_test, _ = abu.run_loop_back(read_cash,\n",
    "                                                   buy_factors,\n",
    "                                                   sell_factors,\n",
    "                                                   start='2014-07-26',\n",
    "                                                   end='2016-07-26',\n",
    "                                                   choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:247\n",
      "胜率:41.2955%\n",
      "平均获利期望:9.7208%\n",
      "平均亏损期望:-4.8754%\n",
      "盈亏比:1.3725\n",
      "所有交易收益比例和:2.8459 \n",
      "所有交易总盈亏和:428259.7700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到使用新的裁判胜率和盈亏比都稍微有提高，可以再加上几个内置裁判一起决策，如下示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 开启内置跳空主裁\n",
    "abupy.env.g_enable_ump_main_jump_block = True\n",
    "# 开启内置价格主裁\n",
    "abupy.env.g_enable_ump_main_price_block = True\n",
    "\n",
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 把新的裁判AbuUmpMainMul类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpMainMul)\n",
    "\n",
    "abu_result_tuple_test_ump_builtin_and_user, _ = abu.run_loop_back(read_cash,\n",
    "                                                                   buy_factors,\n",
    "                                                                   sell_factors,\n",
    "                                                                   start='2014-07-26',\n",
    "                                                                   end='2016-07-26',\n",
    "                                                                   choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:112\n",
      "胜率:44.6429%\n",
      "平均获利期望:11.8156%\n",
      "平均亏损期望:-4.8241%\n",
      "盈亏比:1.8417\n",
      "所有交易收益比例和:2.9169 \n",
      "所有交易总盈亏和:397637.2700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_builtin_and_user, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 从不同视角训练新的边裁\n",
    "\n",
    "和主裁类似，如下示例编写如何从不同视角组成边裁AbuUmpMainMul，其关心的视角为短线21天趋势角度，长线一年的价格rank，长线波动，以及atr波动如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuUmpEdgeMul(AbuUmpEdgeBase, BuyUmpMixin):\n",
    "    \"\"\"从不同视角训练新的边裁示例，AbuUmpEdgeBase子类，混入BuyUmpMixin，做为买入ump类\"\"\"\n",
    "\n",
    "    class UmpMulFiter(AbuMLPd):\n",
    "        @ump.ump_edge_make_xy\n",
    "        def make_xy(self, **kwarg):\n",
    "            filter_list = ['profit', 'profit_cg']\n",
    "            # ['profit', 'profit_cg', 'buy_deg_ang21', 'buy_price_rank252', 'buy_wave_score3', 'buy_atr_std']\n",
    "            filter_list.extend(\n",
    "                [feature.AbuFeatureDeg().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                 feature.AbuFeaturePrice().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                 feature.AbuFeatureWave().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                 feature.AbuFeatureAtr().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1]])\n",
    "            mul_df = self.order_has_ret.filter(filter_list)\n",
    "            return mul_df\n",
    "\n",
    "    def get_predict_col(self):\n",
    "        \"\"\"\n",
    "        边裁单混特征keys：['buy_deg_ang21', 'buy_price_rank252', 'buy_wave_score3', 'buy_atr_std']\n",
    "        :return: ['buy_deg_ang21', 'buy_price_rank252', 'buy_wave_score3', 'buy_atr_std']\n",
    "        \"\"\"\n",
    "\n",
    "        return [feature.AbuFeatureDeg().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                feature.AbuFeaturePrice().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                feature.AbuFeatureWave().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1],\n",
    "                feature.AbuFeatureAtr().get_feature_ump_keys(ump_cls=AbuUmpEdgeMul)[-1]]\n",
    "\n",
    "    def get_fiter_class(self):\n",
    "        \"\"\"\n",
    "        边裁单混特征返回的AbuMLPd子类：AbuUmpEdgeMul.UmpMulFiter\n",
    "        :return: AbuUmpEdgeMul.UmpMulFiter\n",
    "        \"\"\"\n",
    "        return AbuUmpEdgeMul.UmpMulFiter\n",
    "\n",
    "    @classmethod\n",
    "    def class_unique_id(cls):\n",
    "        \"\"\"\n",
    "         具体ump类关键字唯一名称，类方法：return 'mul_edge'\n",
    "         主要针对外部user设置自定义ump使用, 需要user自己保证class_unique_id的唯一性，内部不做检测\n",
    "         具体使用见ABuUmpManager中extend_ump_block方法\n",
    "        \"\"\"\n",
    "        return 'mul_edge'\n",
    "    \n",
    "# 通过import的方式导入AbuUmpEdgeMul, 因为在windows系统上，启动并行后，在ipython notebook中定义的类会在子进程中无法找到\n",
    "from abupy import AbuUmpEdgeMul"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上所示，即完成一个全新ump边裁的编写，与主裁的实现非常类似：\n",
    "\n",
    "1. ump边裁需要继承AbuUmpEdgeBase，买入ump需要混入BuyUmpMixin\n",
    "2. 编写内部类继承自AbuMLPd，实现make_xy，即从训练集数据中筛选自己关心的特征\n",
    "3. 实现get_predict_col，返回关心的特征字符串名称\n",
    "4. 实现get_fiter_class，返回继承自AbuMLPd的内部类\n",
    "5. 实现class_unique_id，为裁判起一个唯一的名称\n",
    "\n",
    "备注：feature.AbuFeatureDeg()等为abupy中内置的特征类，稍后会讲解自定义特征类\n",
    "\n",
    "现在有了新的边裁AbuUmpEdgeMul，接下使用相同的训练集开始训练裁判，和第17节一样使用ump_edge_clf_dump："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "please wait! dump_pickle....: /Users/Bailey/abu/data/ump/ump_edge_umpmulfiter\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>profit</th>\n",
       "      <th>profit_cg</th>\n",
       "      <th>buy_deg_ang21</th>\n",
       "      <th>buy_price_rank252</th>\n",
       "      <th>buy_wave_score3</th>\n",
       "      <th>buy_atr_std</th>\n",
       "      <th>p_rk_cg</th>\n",
       "      <th>rk</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>4368.00</td>\n",
       "      <td>0.0271</td>\n",
       "      <td>2.255</td>\n",
       "      <td>0.857</td>\n",
       "      <td>0.441</td>\n",
       "      <td>1.159</td>\n",
       "      <td>99.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>-11707.50</td>\n",
       "      <td>-0.0588</td>\n",
       "      <td>1.837</td>\n",
       "      <td>0.798</td>\n",
       "      <td>-0.001</td>\n",
       "      <td>1.281</td>\n",
       "      <td>47.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>23360.00</td>\n",
       "      <td>0.1170</td>\n",
       "      <td>2.357</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.232</td>\n",
       "      <td>2.033</td>\n",
       "      <td>142.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>20410.88</td>\n",
       "      <td>0.1021</td>\n",
       "      <td>0.931</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.289</td>\n",
       "      <td>0.192</td>\n",
       "      <td>137.5</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>20410.88</td>\n",
       "      <td>0.1021</td>\n",
       "      <td>0.931</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.289</td>\n",
       "      <td>0.192</td>\n",
       "      <td>137.5</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              profit  profit_cg  buy_deg_ang21  buy_price_rank252  \\\n",
       "2014-09-25   4368.00     0.0271          2.255              0.857   \n",
       "2014-10-09 -11707.50    -0.0588          1.837              0.798   \n",
       "2014-10-17  23360.00     0.1170          2.357              1.000   \n",
       "2014-10-24  20410.88     0.1021          0.931              1.000   \n",
       "2014-10-24  20410.88     0.1021          0.931              1.000   \n",
       "\n",
       "            buy_wave_score3  buy_atr_std  p_rk_cg  rk  \n",
       "2014-09-25            0.441        1.159     99.0   0  \n",
       "2014-10-09           -0.001        1.281     47.0   0  \n",
       "2014-10-17            0.232        2.033    142.0   0  \n",
       "2014-10-24            1.289        0.192    137.5   0  \n",
       "2014-10-24            1.289        0.192    137.5   0  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "edge_mul = AbuUmpEdgeMul.ump_edge_clf_dump(orders_pd_train)\n",
    "edge_mul.fiter.df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "显示的特征为新的边裁AbuUmpEdgeMul所关心的决策视角和行为。\n",
    "\n",
    "\n",
    "下面将新的边裁添加到系统中流程为：\n",
    "\n",
    "1. 打开使用用户自定义裁判开关：ump.manager.g_enable_user_ump = True\n",
    "2. 把新的裁判AbuUmpEdgeMul类名称使用append_user_ump添加到系统中，或者直接将上面训练好的对象edge_mul添加也可以\n",
    "\n",
    "流程和主裁一致，这里使用ump.manager.clear_user_ump()先把自定义裁判清空一下，即将上面添加到系统中自定义主裁清除。\n",
    "\n",
    "备注：使用append_user_ump添加的裁判参数可以是类名称，也可以是类对象，但边裁必须是使用ump_edge_clf_dump训练好的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 清空用户自定义的裁判\n",
    "ump.manager.clear_user_ump()\n",
    "\n",
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 把新的裁判AbuUmpEdgeMul类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpEdgeMul)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "abu_result_tuple_test_ump_user_edge, _ = abu.run_loop_back(read_cash,\n",
    "                                                   buy_factors,\n",
    "                                                   sell_factors,\n",
    "                                                   start='2014-07-26',\n",
    "                                                   end='2016-07-26',\n",
    "                                                   choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:109\n",
      "胜率:44.0367%\n",
      "平均获利期望:9.4283%\n",
      "平均亏损期望:-4.5710%\n",
      "盈亏比:1.5630\n",
      "所有交易收益比例和:1.7373 \n",
      "所有交易总盈亏和:252098.5300 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_user_edge, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到使用新的边裁胜率和盈亏比并不太理想，可以再加上几个内置边裁一起决策，如下示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 开启内置价格边裁\n",
    "abupy.env.g_enable_ump_edge_price_block = True\n",
    "# 开启内置波动边裁\n",
    "abupy.env.g_enable_ump_edge_wave_block = True\n",
    "\n",
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 把新的裁判AbuUmpEdgeMul类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpEdgeMul)\n",
    "\n",
    "abu_result_tuple_test_ump_builtin_and_user_edge, _ = abu.run_loop_back(read_cash,\n",
    "                                                                       buy_factors,\n",
    "                                                                       sell_factors,\n",
    "                                                                       start='2014-07-26',\n",
    "                                                                       end='2016-07-26',\n",
    "                                                                       choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:66\n",
      "胜率:56.0606%\n",
      "平均获利期望:10.3395%\n",
      "平均亏损期望:-4.5154%\n",
      "盈亏比:2.6907\n",
      "所有交易收益比例和:2.5161 \n",
      "所有交易总盈亏和:357671.0300 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_builtin_and_user_edge, returns_cmp=True, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的完成的裁判都是使用abupy内置的特征类，如果希望能裁判能够从一些新的视角或者行为来进行决策，那么就需要添加新的视角来录制比赛(回测交易)，下面的内容将示例讲自定义新的特征类（新的视角），自定义裁判使用这些新的特征类进行训练：\n",
    "\n",
    "### 3. 添加新的视角来录制比赛（记录回测特征）\n",
    "\n",
    "如下示例如何添加新的视角来录制比赛，编写AbuFeatureDegExtend，其与内置的角度主裁使用的特征很像，也是录制买入，卖出时的拟合角度特征 主裁角度记录21，42，60，252日走势拟合角度，本示例记录10，30，50，90，120日走势拟合角度特征，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuFeatureDegExtend(AbuFeatureBase, BuyFeatureMixin, SellFeatureMixin):\n",
    "    \"\"\"示例添加新的视角来录制比赛，角度特征，支持买入，卖出\"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        \"\"\"20, 40, 60, 90, 120日走势角度特征\"\"\"\n",
    "        # frozenset包一下，一旦定下来就不能修改，否则特征对不上\n",
    "        self.deg_keys = frozenset([10, 30, 50, 90, 120])\n",
    "\n",
    "    def get_feature_keys(self, buy_feature):\n",
    "        \"\"\"\n",
    "        迭代生成所有走势角度特征feature的列名称定, 使用feature_prefix区分买入，卖出前缀key\n",
    "        :param buy_feature: 是否是买入特征构造（bool）\n",
    "        :return: 角度特征的键值对字典中的key序列\n",
    "        \"\"\"\n",
    "        return ['{}deg_ang{}'.format(self.feature_prefix(buy_feature=buy_feature), dk) for dk in self.deg_keys]\n",
    "\n",
    "    def calc_feature(self, kl_pd, combine_kl_pd, day_ind, buy_feature):\n",
    "        \"\"\"\n",
    "        根据买入或者卖出时的金融时间序列，以及交易日信息构造拟合角度特征\n",
    "        :param kl_pd: 择时阶段金融时间序列\n",
    "        :param combine_kl_pd: 合并择时阶段之前1年的金融时间序列\n",
    "        :param day_ind: 交易发生的时间索引，即对应self.kl_pd.key\n",
    "        :param buy_feature: 是否是买入特征构造（bool）\n",
    "        :return: 构造角度特征的键值对字典\n",
    "        \"\"\"\n",
    "        # 返回的角度特征键值对字典\n",
    "        deg_dict = {}\n",
    "        for dk in self.deg_keys:\n",
    "            # 迭代预设角度周期，计算构建特征\n",
    "            if day_ind - dk >= 0:\n",
    "                # 如果择时时间序列够提取特征，使用kl_pd截取特征交易周期收盘价格\n",
    "                deg_close = kl_pd[day_ind - dk + 1:day_ind + 1].close\n",
    "            else:\n",
    "                # 如果择时时间序列不够提取特征，使用combine_kl_pd截取特征交易周期，首先截取直到day_ind的时间序列\n",
    "                combine_kl_pd = combine_kl_pd.loc[:kl_pd.index[day_ind]]\n",
    "                # 如combine_kl_pd长度大于特征周期长度－> 截取combine_kl_pd[-dk:].close，否则取combine_kl_pd所有交易收盘价格\n",
    "                deg_close = combine_kl_pd[-dk:].close if combine_kl_pd.shape[0] > dk else combine_kl_pd.close\n",
    "\n",
    "            # 使用截取特征交易周期收盘价格deg_close做为参数，通过calc_regress_deg计算趋势拟合角度\n",
    "            ang = ABuRegUtil.calc_regress_deg(deg_close, show=False)\n",
    "            # 标准化拟合角度值\n",
    "            ang = 0 if np.isnan(ang) else round(ang, 3)\n",
    "            # 角度特征键值对字典添加拟合角度周期key和对应的拟合角度值\n",
    "            deg_dict['{}deg_ang{}'.format(self.feature_prefix(buy_feature=buy_feature), dk)] = ang\n",
    "        return deg_dict\n",
    "    \n",
    "# 通过import的方式导入AbuFeatureDegExtend, 因为在windows系统上，启动并行后，在ipython notebook中定义的类会在子进程中无法找到\n",
    "from abupy import AbuFeatureDegExtend"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上所示，即添加完成一个新的视角来录制比赛（回测交易），即用户自定义特征类：\n",
    "\n",
    "1. 特征类需要继承AbuFeatureBase，支持买入特征混入BuyFeatureMixin，支持卖出特征混入SellFeatureMixin，本例都支持，都混入\n",
    "4. 需要实现get_feature_keys，返回自定义特征列名称\n",
    "5. 需要实现calc_feature，根据参数中的金融时间数据计算具体的特征值\n",
    "\n",
    "备注：更多特征类的编写示例请阅读ABuMLFeature中相关源代码\n",
    "\n",
    "现在有了新的特征类AbuFeatureDegExtend，首先需要使用feature.append_user_feature将新的特征加入到系统中："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "feature.append_user_feature(AbuFeatureDegExtend)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在新的特征类已经在系统中了，使用第15节回测的相同设置进行回测，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:196\n",
      "胜率:59.6939%\n",
      "平均获利期望:18.6899%\n",
      "平均亏损期望:-7.1235%\n",
      "盈亏比:4.4972\n",
      "所有交易收益比例和:16.2396 \n",
      "所有交易总盈亏和:2717948.4900 \n"
     ]
    }
   ],
   "source": [
    "# 关闭内置跳空主裁\n",
    "abupy.env.g_enable_ump_main_jump_block = False\n",
    "# 关闭内置价格主裁\n",
    "abupy.env.g_enable_ump_main_price_block = False\n",
    "# 关闭内置角度主裁\n",
    "abupy.env.g_enable_ump_main_deg_block = False\n",
    "# 关闭内置波动主裁\n",
    "abupy.env.g_enable_ump_main_wave_block = False\n",
    "\n",
    "# 关闭内置价格边裁\n",
    "abupy.env.g_enable_ump_edge_price_block = False\n",
    "# 关闭内置波动边裁\n",
    "abupy.env.g_enable_ump_edge_wave_block = False\n",
    "# 关闭内置角度边裁\n",
    "abupy.env.g_enable_ump_edge_deg_block = False\n",
    "# 关闭内置综合边裁\n",
    "abupy.env.g_enable_ump_edge_full_block = False\n",
    "\n",
    "# 关闭用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = False\n",
    "\n",
    "abu_result_tuple_train_deg_extend, _ = abu.run_loop_back(read_cash,\n",
    "                                                       buy_factors,\n",
    "                                                       sell_factors,\n",
    "                                                       start='2014-07-26',\n",
    "                                                       end='2016-07-26',\n",
    "                                                       choice_symbols=train_choice_symbols)\n",
    "ABuProgress.clear_output()\n",
    "orders_pd_train_deg_extend = abu_result_tuple_train_deg_extend.orders_pd\n",
    "AbuMetricsBase.show_general(*abu_result_tuple_train_deg_extend, returns_cmp=True ,only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以发现回测的度量结果和之前是一摸一样的，不同点在于orders_pd_train_deg_extend中有了新的特征，如下筛选出所有拟合角特征："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>buy_deg_ang42</th>\n",
       "      <th>buy_deg_ang252</th>\n",
       "      <th>buy_deg_ang60</th>\n",
       "      <th>buy_deg_ang21</th>\n",
       "      <th>buy_deg_ang10</th>\n",
       "      <th>buy_deg_ang50</th>\n",
       "      <th>buy_deg_ang120</th>\n",
       "      <th>buy_deg_ang90</th>\n",
       "      <th>buy_deg_ang30</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>7.168</td>\n",
       "      <td>-3.708</td>\n",
       "      <td>4.342</td>\n",
       "      <td>2.255</td>\n",
       "      <td>0.137</td>\n",
       "      <td>8.306</td>\n",
       "      <td>4.676</td>\n",
       "      <td>8.181</td>\n",
       "      <td>2.718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>-0.567</td>\n",
       "      <td>-6.527</td>\n",
       "      <td>1.309</td>\n",
       "      <td>1.837</td>\n",
       "      <td>1.334</td>\n",
       "      <td>-1.432</td>\n",
       "      <td>9.219</td>\n",
       "      <td>8.100</td>\n",
       "      <td>0.891</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>2.328</td>\n",
       "      <td>4.764</td>\n",
       "      <td>2.096</td>\n",
       "      <td>2.357</td>\n",
       "      <td>2.849</td>\n",
       "      <td>2.365</td>\n",
       "      <td>15.344</td>\n",
       "      <td>11.823</td>\n",
       "      <td>0.549</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>-0.454</td>\n",
       "      <td>5.532</td>\n",
       "      <td>2.142</td>\n",
       "      <td>0.931</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>-0.454</td>\n",
       "      <td>5.532</td>\n",
       "      <td>2.142</td>\n",
       "      <td>0.931</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            buy_deg_ang42  buy_deg_ang252  buy_deg_ang60  buy_deg_ang21  \\\n",
       "2014-09-25          7.168          -3.708          4.342          2.255   \n",
       "2014-10-09         -0.567          -6.527          1.309          1.837   \n",
       "2014-10-17          2.328           4.764          2.096          2.357   \n",
       "2014-10-24         -0.454           5.532          2.142          0.931   \n",
       "2014-10-24         -0.454           5.532          2.142          0.931   \n",
       "\n",
       "            buy_deg_ang10  buy_deg_ang50  buy_deg_ang120  buy_deg_ang90  \\\n",
       "2014-09-25          0.137          8.306           4.676          8.181   \n",
       "2014-10-09          1.334         -1.432           9.219          8.100   \n",
       "2014-10-17          2.849          2.365          15.344         11.823   \n",
       "2014-10-24          2.559         -0.019           5.532          5.165   \n",
       "2014-10-24          2.559         -0.019           5.532          5.165   \n",
       "\n",
       "            buy_deg_ang30  \n",
       "2014-09-25          2.718  \n",
       "2014-10-09          0.891  \n",
       "2014-10-17          0.549  \n",
       "2014-10-24         -0.573  \n",
       "2014-10-24         -0.573  "
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "orders_pd_train_deg_extend.filter(regex='buy_*deg').head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到除了之前主裁使用的拟合角度21，42，60，252，外还增加了10，30，50，90，120日拟合角度特征值，下面把AbuFeatureDegExtend的特征都筛选出来看看："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>buy_deg_ang10</th>\n",
       "      <th>buy_deg_ang50</th>\n",
       "      <th>buy_deg_ang120</th>\n",
       "      <th>buy_deg_ang90</th>\n",
       "      <th>buy_deg_ang30</th>\n",
       "      <th>sell_deg_ang10</th>\n",
       "      <th>sell_deg_ang50</th>\n",
       "      <th>sell_deg_ang120</th>\n",
       "      <th>sell_deg_ang90</th>\n",
       "      <th>sell_deg_ang30</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>0.137</td>\n",
       "      <td>8.306</td>\n",
       "      <td>4.676</td>\n",
       "      <td>8.181</td>\n",
       "      <td>2.718</td>\n",
       "      <td>-2.254</td>\n",
       "      <td>10.901</td>\n",
       "      <td>11.390</td>\n",
       "      <td>9.258</td>\n",
       "      <td>7.129</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>1.334</td>\n",
       "      <td>-1.432</td>\n",
       "      <td>9.219</td>\n",
       "      <td>8.100</td>\n",
       "      <td>0.891</td>\n",
       "      <td>0.487</td>\n",
       "      <td>0.789</td>\n",
       "      <td>8.779</td>\n",
       "      <td>3.912</td>\n",
       "      <td>-0.955</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>2.849</td>\n",
       "      <td>2.365</td>\n",
       "      <td>15.344</td>\n",
       "      <td>11.823</td>\n",
       "      <td>0.549</td>\n",
       "      <td>0.000</td>\n",
       "      <td>0.381</td>\n",
       "      <td>11.407</td>\n",
       "      <td>8.627</td>\n",
       "      <td>-0.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "      <td>0.391</td>\n",
       "      <td>10.244</td>\n",
       "      <td>10.358</td>\n",
       "      <td>8.946</td>\n",
       "      <td>7.452</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "      <td>0.391</td>\n",
       "      <td>10.244</td>\n",
       "      <td>10.358</td>\n",
       "      <td>8.946</td>\n",
       "      <td>7.452</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            buy_deg_ang10  buy_deg_ang50  buy_deg_ang120  buy_deg_ang90  \\\n",
       "2014-09-25          0.137          8.306           4.676          8.181   \n",
       "2014-10-09          1.334         -1.432           9.219          8.100   \n",
       "2014-10-17          2.849          2.365          15.344         11.823   \n",
       "2014-10-24          2.559         -0.019           5.532          5.165   \n",
       "2014-10-24          2.559         -0.019           5.532          5.165   \n",
       "\n",
       "            buy_deg_ang30  sell_deg_ang10  sell_deg_ang50  sell_deg_ang120  \\\n",
       "2014-09-25          2.718          -2.254          10.901           11.390   \n",
       "2014-10-09          0.891           0.487           0.789            8.779   \n",
       "2014-10-17          0.549           0.000           0.381           11.407   \n",
       "2014-10-24         -0.573           0.391          10.244           10.358   \n",
       "2014-10-24         -0.573           0.391          10.244           10.358   \n",
       "\n",
       "            sell_deg_ang90  sell_deg_ang30  \n",
       "2014-09-25           9.258           7.129  \n",
       "2014-10-09           3.912          -0.955  \n",
       "2014-10-17           8.627          -0.000  \n",
       "2014-10-24           8.946           7.452  \n",
       "2014-10-24           8.946           7.452  "
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "orders_pd_train_deg_extend.filter(AbuFeatureDegExtend().get_feature_keys(True) +\n",
    "                                  AbuFeatureDegExtend().get_feature_keys(False)).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到由于AbuFeatureDegExtend混入了BuyFeatureMixin和SellFeatureMixin，所以同时生成了买入趋势角度特征和卖出趋势角度特征，买入特征就是在之前的章节中主裁和边裁使用的特征，之前的章节讲解的都是根据买入特征进行决策拦截，没有涉及过针对卖出的交易进行决策拦截的示例，在之后的章节中会完整示例，请关注公众号的更新提醒。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. 主裁使用新的视角来决策交易\n",
    "\n",
    "下面开始编写主裁使用AbuFeatureDegExtend："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuUmpMainDegExtend(AbuUmpMainBase, BuyUmpMixin):\n",
    "    \"\"\"主裁使用新的视角来决策交易，AbuUmpMainBase子类，混入BuyUmpMixin，做为买入ump类\"\"\"\n",
    "    \n",
    "    class UmpExtendFeatureFiter(AbuMLPd):\n",
    "        @ump.ump_main_make_xy\n",
    "        def make_xy(self, **kwarg):\n",
    "            # 这里使用get_feature_ump_keys，只需要传递当前类名称即可，其根据是买入ump还是卖出ump返回对应特征列\n",
    "            col = AbuFeatureDegExtend().get_feature_ump_keys(ump_cls=AbuUmpMainDegExtend)\n",
    "            regex = 'result|{}'.format('|'.join(col))\n",
    "            extend_deg_df = self.order_has_ret.filter(regex=regex)\n",
    "            return extend_deg_df\n",
    "\n",
    "    def get_predict_col(self):\n",
    "        # 这里使用get_feature_ump_keys，只需要传递当前类名称即可，其根据是买入ump还是卖出ump返回对应特征列\n",
    "        col = AbuFeatureDegExtend().get_feature_ump_keys(ump_cls=AbuUmpMainDegExtend)\n",
    "        return col\n",
    "\n",
    "    def get_fiter_class(self):\n",
    "        return AbuUmpMainDegExtend.UmpExtendFeatureFiter\n",
    "\n",
    "    @classmethod\n",
    "    def class_unique_id(cls):\n",
    "        return 'extend_main_deg'\n",
    "    \n",
    "# 通过import的方式导入AbuUmpMainDegExtend, 因为在windows系统上，启动并行后，在ipython notebook中定义的类会在子进程中无法找到\n",
    "from abupy import AbuUmpMainDegExtend"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "AbuUmpMainDegExtend的编写与之前类似，接下来使用AbuUmpMainDegExtend进行测试集回测，仍然不要忘记要先训练裁判，然后使用append_user_ump添加到系统中："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "please wait! dump_pickle....: /Users/Bailey/abu/data/ump/ump_main_umpextendfeaturefiter\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>result</th>\n",
       "      <th>buy_deg_ang10</th>\n",
       "      <th>buy_deg_ang50</th>\n",
       "      <th>buy_deg_ang120</th>\n",
       "      <th>buy_deg_ang90</th>\n",
       "      <th>buy_deg_ang30</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>1</td>\n",
       "      <td>0.137</td>\n",
       "      <td>8.306</td>\n",
       "      <td>4.676</td>\n",
       "      <td>8.181</td>\n",
       "      <td>2.718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>0</td>\n",
       "      <td>1.334</td>\n",
       "      <td>-1.432</td>\n",
       "      <td>9.219</td>\n",
       "      <td>8.100</td>\n",
       "      <td>0.891</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>1</td>\n",
       "      <td>2.849</td>\n",
       "      <td>2.365</td>\n",
       "      <td>15.344</td>\n",
       "      <td>11.823</td>\n",
       "      <td>0.549</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>1</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>1</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            result  buy_deg_ang10  buy_deg_ang50  buy_deg_ang120  \\\n",
       "2014-09-25       1          0.137          8.306           4.676   \n",
       "2014-10-09       0          1.334         -1.432           9.219   \n",
       "2014-10-17       1          2.849          2.365          15.344   \n",
       "2014-10-24       1          2.559         -0.019           5.532   \n",
       "2014-10-24       1          2.559         -0.019           5.532   \n",
       "\n",
       "            buy_deg_ang90  buy_deg_ang30  \n",
       "2014-09-25          8.181          2.718  \n",
       "2014-10-09          8.100          0.891  \n",
       "2014-10-17         11.823          0.549  \n",
       "2014-10-24          5.165         -0.573  \n",
       "2014-10-24          5.165         -0.573  "
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 首先训练新裁判AbuUmpMainDegExtend，注意这里训练要使用orders_pd_train_deg_extend，不能用之前的orders_pd_train，否则没有特征列\n",
    "ump_deg_extend = AbuUmpMainDegExtend.ump_main_clf_dump(orders_pd_train_deg_extend, p_ncs=slice(20, 40, 1))\n",
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 先clear一下\n",
    "ump.manager.clear_user_ump()\n",
    "# 把新的裁判AbuUmpMainDegExtend类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpMainDegExtend)\n",
    "\n",
    "ump_deg_extend.fiter.df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "abu_result_tuple_test_ump_extend_deg, _ = abu.run_loop_back(read_cash,\n",
    "                                                               buy_factors,\n",
    "                                                               sell_factors,\n",
    "                                                               start='2014-07-26',\n",
    "                                                               end='2016-07-26',\n",
    "                                                               choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:232\n",
      "胜率:42.2414%\n",
      "平均获利期望:9.3664%\n",
      "平均亏损期望:-4.8751%\n",
      "盈亏比:1.3626\n",
      "所有交易收益比例和:2.6464 \n",
      "所有交易总盈亏和:382564.7700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_extend_deg, returns_cmp=True ,only_info=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正确拦截失败的交易数量11, 错误拦截的交易数量4\n"
     ]
    }
   ],
   "source": [
    "proxy = AbuOrderPdProxy(abu_result_tuple_test.orders_pd)\n",
    "with proxy.proxy_work(abu_result_tuple_test_ump_extend_deg.orders_pd) as (order1, order2):\n",
    "     block_order = order1 - order2\n",
    "print('正确拦截失败的交易数量{}, 错误拦截的交易数量{}'.format(block_order.result.value_counts()[-1], block_order.result.value_counts()[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上所示拦截了15笔交易，11笔正确，拦截正确率比较高，达到73%正确。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. 边裁使用新的视角来决策交易\n",
    "\n",
    "下面开始编写边裁使用AbuFeatureDegExtend："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuUmpEegeDegExtend(AbuUmpEdgeBase, BuyUmpMixin):\n",
    "    \"\"\"边裁使用新的视角来决策交易，AbuUmpEdgeBase子类，混入BuyUmpMixin，做为买入ump类\"\"\"\n",
    "\n",
    "    class UmpExtendEdgeFiter(AbuMLPd):\n",
    "        @ump.ump_edge_make_xy\n",
    "        def make_xy(self, **kwarg):\n",
    "            filter_list = ['profit', 'profit_cg']\n",
    "            col = AbuFeatureDegExtend().get_feature_ump_keys(ump_cls=AbuUmpEegeDegExtend)\n",
    "            filter_list.extend(col)\n",
    "            mul_df = self.order_has_ret.filter(filter_list)\n",
    "            return mul_df\n",
    "\n",
    "    def get_predict_col(self):\n",
    "        # 这里使用get_feature_ump_keys，只需要传递当前类名称即可，其根据是买入ump还是卖出ump返回对应特征列\n",
    "        col = AbuFeatureDegExtend().get_feature_ump_keys(ump_cls=AbuUmpEegeDegExtend)\n",
    "        return col\n",
    "\n",
    "    def get_fiter_class(self):\n",
    "        return AbuUmpEegeDegExtend.UmpExtendEdgeFiter\n",
    "\n",
    "    @classmethod\n",
    "    def class_unique_id(cls):\n",
    "        return 'extend_edge_deg'\n",
    "    \n",
    "# 通过import的方式导入AbuUmpEegeDegExtend, 因为在windows系统上，启动并行后，在ipython notebook中定义的类会在子进程中无法找到\n",
    "from abupy import AbuUmpEegeDegExtend"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "AbuUmpEegeDegExtend的编写与之前类似，接下来使用AbuUmpEegeDegExtend进行测试集回测，仍然不要忘记要先训练裁判，然后使用append_user_ump添加到系统中："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "please wait! dump_pickle....: /Users/Bailey/abu/data/ump/ump_edge_umpextendedgefiter\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>profit</th>\n",
       "      <th>profit_cg</th>\n",
       "      <th>buy_deg_ang10</th>\n",
       "      <th>buy_deg_ang50</th>\n",
       "      <th>buy_deg_ang120</th>\n",
       "      <th>buy_deg_ang90</th>\n",
       "      <th>buy_deg_ang30</th>\n",
       "      <th>p_rk_cg</th>\n",
       "      <th>rk</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-09-25</th>\n",
       "      <td>4368.00</td>\n",
       "      <td>0.0271</td>\n",
       "      <td>0.137</td>\n",
       "      <td>8.306</td>\n",
       "      <td>4.676</td>\n",
       "      <td>8.181</td>\n",
       "      <td>2.718</td>\n",
       "      <td>99.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-09</th>\n",
       "      <td>-11707.50</td>\n",
       "      <td>-0.0588</td>\n",
       "      <td>1.334</td>\n",
       "      <td>-1.432</td>\n",
       "      <td>9.219</td>\n",
       "      <td>8.100</td>\n",
       "      <td>0.891</td>\n",
       "      <td>47.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-17</th>\n",
       "      <td>23360.00</td>\n",
       "      <td>0.1170</td>\n",
       "      <td>2.849</td>\n",
       "      <td>2.365</td>\n",
       "      <td>15.344</td>\n",
       "      <td>11.823</td>\n",
       "      <td>0.549</td>\n",
       "      <td>142.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>20410.88</td>\n",
       "      <td>0.1021</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "      <td>137.5</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-10-24</th>\n",
       "      <td>20410.88</td>\n",
       "      <td>0.1021</td>\n",
       "      <td>2.559</td>\n",
       "      <td>-0.019</td>\n",
       "      <td>5.532</td>\n",
       "      <td>5.165</td>\n",
       "      <td>-0.573</td>\n",
       "      <td>137.5</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              profit  profit_cg  buy_deg_ang10  buy_deg_ang50  buy_deg_ang120  \\\n",
       "2014-09-25   4368.00     0.0271          0.137          8.306           4.676   \n",
       "2014-10-09 -11707.50    -0.0588          1.334         -1.432           9.219   \n",
       "2014-10-17  23360.00     0.1170          2.849          2.365          15.344   \n",
       "2014-10-24  20410.88     0.1021          2.559         -0.019           5.532   \n",
       "2014-10-24  20410.88     0.1021          2.559         -0.019           5.532   \n",
       "\n",
       "            buy_deg_ang90  buy_deg_ang30  p_rk_cg  rk  \n",
       "2014-09-25          8.181          2.718     99.0   0  \n",
       "2014-10-09          8.100          0.891     47.0   0  \n",
       "2014-10-17         11.823          0.549    142.0   0  \n",
       "2014-10-24          5.165         -0.573    137.5   0  \n",
       "2014-10-24          5.165         -0.573    137.5   0  "
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 首先训练新裁判AbuUmpMainDegExtend，注意这里训练要使用orders_pd_train_deg_extend，不能用之前的orders_pd_train，否则没有特征列\n",
    "ump_deg_edge_extend = AbuUmpEegeDegExtend.ump_edge_clf_dump(orders_pd_train_deg_extend)\n",
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 先clear一下\n",
    "ump.manager.clear_user_ump()\n",
    "# 把新的裁判AbuUmpMainDegExtend类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpEegeDegExtend)\n",
    "\n",
    "ump_deg_edge_extend.fiter.df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "abu_result_tuple_test_ump_edge_extend_deg, _ = abu.run_loop_back(read_cash,\n",
    "                                                               buy_factors,\n",
    "                                                               sell_factors,\n",
    "                                                               start='2014-07-26',\n",
    "                                                               end='2016-07-26',\n",
    "                                                               choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:235\n",
      "胜率:42.1277%\n",
      "平均获利期望:9.5267%\n",
      "平均亏损期望:-4.8764%\n",
      "盈亏比:1.3821\n",
      "所有交易收益比例和:2.7995 \n",
      "所有交易总盈亏和:410764.7700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_edge_extend_deg, returns_cmp=True ,only_info=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正确拦截失败的交易数量9, 错误拦截的交易数量3\n"
     ]
    }
   ],
   "source": [
    "proxy = AbuOrderPdProxy(abu_result_tuple_test.orders_pd)\n",
    "with proxy.proxy_work(abu_result_tuple_test_ump_extend_deg.orders_pd) as (order1, order2):\n",
    "     block_order = order1 - order2\n",
    "print('正确拦截失败的交易数量{}, 错误拦截的交易数量{}'.format(block_order.result.value_counts()[-1], block_order.result.value_counts()[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上所示拦截了12笔交易，9笔正确，拦截正确率比较高，达到75%正确。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后使用新编写的主裁趋势角度扩展类，边裁趋势角度扩展类，和内置的主裁角度，内置的边裁角度共同决进行回测："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 打开使用用户自定义裁判开关\n",
    "ump.manager.g_enable_user_ump = True\n",
    "# 先clear一下\n",
    "ump.manager.clear_user_ump()\n",
    "\n",
    "# 把新的裁判AbuUmpMainDegExtend类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpEegeDegExtend)\n",
    "# 把新的裁判AbuUmpMainDegExtend类名称使用append_user_ump添加到系统中\n",
    "ump.manager.append_user_ump(AbuUmpMainDegExtend)\n",
    "\n",
    "# 打开内置角度边裁\n",
    "abupy.env.g_enable_ump_edge_deg_block = True\n",
    "# 打开内置角度主裁\n",
    "abupy.env.g_enable_ump_main_deg_block = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "abu_result_tuple_test_ump_end, _ = abu.run_loop_back(read_cash,\n",
    "                                                               buy_factors,\n",
    "                                                               sell_factors,\n",
    "                                                               start='2014-07-26',\n",
    "                                                               end='2016-07-26',\n",
    "                                                               choice_symbols=test_choice_symbols)\n",
    "ABuProgress.clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:192\n",
      "胜率:42.7083%\n",
      "平均获利期望:9.4539%\n",
      "平均亏损期望:-4.8478%\n",
      "盈亏比:1.3774\n",
      "所有交易收益比例和:2.4196 \n",
      "所有交易总盈亏和:325569.7700 \n"
     ]
    }
   ],
   "source": [
    "AbuMetricsBase.show_general(*abu_result_tuple_test_ump_end, returns_cmp=True ,only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "小结：\n",
    "\n",
    "abupy中ump模块的设计目标是：\n",
    "\n",
    "1. 不需要在具体策略中硬编码\n",
    "2. 不需要人工设定阀值，即且使得代码逻辑清晰\n",
    "3. 分离基础策略和策略优化监督模块，提高灵活度和适配性\n",
    "4. 发现策略中隐藏的交易策略问题\n",
    "5. 可以通过不断的学习新的交易数据\n",
    "\n",
    "ump的使用和在‘第九节 港股市场的回测’中使用将优化策略的'策略'做为类装饰器进行封装的目的都是：**分离基础策略和策略优化监督模块，提高灵活度和适配性**, 基础策略追求的就应该是简单, **可以一句话说明你的基础策略**。\n",
    "\n",
    "\n",
    "现阶段的量化策略还是通过人来编写代码，未来的发展也许会向着完全由计算机实现整套流程的方向迈进，包括量化策略本身。\n",
    "\n",
    "abupy的设计目标是：\n",
    "\n",
    "只需要提供一些基础的简单种子策略代码，计算机在这些简单种子策略基础上不断自我学习、自我完善，创造新的策略，并且紧跟时间序列不断自我调整策略参数。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "#### abu量化文档目录章节\n",
    "\n",
    "1. [择时策略的开发](http://www.abuquant.com/lecture/lecture_1.html)\n",
    "2. [择时策略的优化](http://www.abuquant.com/lecture/lecture_2.html)\n",
    "3. [滑点策略与交易手续费](http://www.abuquant.com/lecture/lecture_3.html)\n",
    "4. [多支股票择时回测与仓位管理](http://www.abuquant.com/lecture/lecture_4.html)\n",
    "5. [选股策略的开发](http://www.abuquant.com/lecture/lecture_5.html)\n",
    "6. [回测结果的度量](http://www.abuquant.com/lecture/lecture_6.html)\n",
    "7. [寻找策略最优参数和评分](http://www.abuquant.com/lecture/lecture_7.html)\n",
    "8. [A股市场的回测](http://www.abuquant.com/lecture/lecture_8.html)\n",
    "9. [港股市场的回测](http://www.abuquant.com/lecture/lecture_9.html)\n",
    "10. [比特币，莱特币的回测](http://www.abuquant.com/lecture/lecture_10.html)\n",
    "11. [期货市场的回测](http://www.abuquant.com/lecture/lecture_11.html)\n",
    "12. [机器学习与比特币示例](http://www.abuquant.com/lecture/lecture_12.html)\n",
    "13. [量化技术分析应用](http://www.abuquant.com/lecture/lecture_13.html)\n",
    "14. [量化相关性分析应用](http://www.abuquant.com/lecture/lecture_14.html)\n",
    "15. [量化交易和搜索引擎](http://www.abuquant.com/lecture/lecture_15.html)\n",
    "16. [UMP主裁交易决策](http://www.abuquant.com/lecture/lecture_16.html)\n",
    "17. [UMP边裁交易决策](http://www.abuquant.com/lecture/lecture_17.html)\n",
    "18. [自定义裁判决策交易](http://www.abuquant.com/lecture/lecture_18.html)\n",
    "19. [数据源](http://www.abuquant.com/lecture/lecture_19.html)\n",
    "20. [A股全市场回测](http://www.abuquant.com/lecture/lecture_20.html)\n",
    "21. [A股UMP决策](http://www.abuquant.com/lecture/lecture_21.html)\n",
    "22. [美股全市场回测](http://www.abuquant.com/lecture/lecture_22.html)\n",
    "23. [美股UMP决策](http://www.abuquant.com/lecture/lecture_23.html)\n",
    "\n",
    "abu量化系统文档教程持续更新中，请关注公众号中的更新提醒。\n",
    "\n",
    "#### 《量化交易之路》目录章节及随书代码地址\n",
    "\n",
    "1. [第二章 量化语言——Python](https://github.com/bbfamily/abu/tree/master/ipython/第二章-量化语言——Python.ipynb)\n",
    "2. [第三章 量化工具——NumPy](https://github.com/bbfamily/abu/tree/master/ipython/第三章-量化工具——NumPy.ipynb)\n",
    "3. [第四章 量化工具——pandas](https://github.com/bbfamily/abu/tree/master/ipython/第四章-量化工具——pandas.ipynb)\n",
    "4. [第五章 量化工具——可视化](https://github.com/bbfamily/abu/tree/master/ipython/第五章-量化工具——可视化.ipynb)\n",
    "5. [第六章 量化工具——数学：你一生的追求到底能带来多少幸福](https://github.com/bbfamily/abu/tree/master/ipython/第六章-量化工具——数学.ipynb)\n",
    "6. [第七章 量化系统——入门：三只小猪股票投资的故事](https://github.com/bbfamily/abu/tree/master/ipython/第七章-量化系统——入门.ipynb)\n",
    "7. [第八章 量化系统——开发](https://github.com/bbfamily/abu/tree/master/ipython/第八章-量化系统——开发.ipynb)\n",
    "8. [第九章 量化系统——度量与优化](https://github.com/bbfamily/abu/tree/master/ipython/第九章-量化系统——度量与优化.ipynb)\n",
    "9. [第十章 量化系统——机器学习•猪老三](https://github.com/bbfamily/abu/tree/master/ipython/第十章-量化系统——机器学习•猪老三.ipynb)\n",
    "10. [第十一章 量化系统——机器学习•ABU](https://github.com/bbfamily/abu/tree/master/ipython/第十一章-量化系统——机器学习•ABU.ipynb)\n",
    "11. [附录A 量化环境部署](https://github.com/bbfamily/abu/tree/master/ipython/附录A-量化环境部署.ipynb)\n",
    "12. [附录B 量化相关性分析](https://github.com/bbfamily/abu/tree/master/ipython/附录B-量化相关性分析.ipynb)\n",
    "13. [附录C 量化统计分析及指标应用](https://github.com/bbfamily/abu/tree/master/ipython/附录C-量化统计分析及指标应用.ipynb)\n",
    "\n",
    "\n",
    "[更多阿布量化量化技术文章](http://www.abuquant.com/article)\n",
    "\n",
    "\n",
    "更多关于量化交易相关请阅读[《量化交易之路》](http://www.abuquant.com/books/quantify-trading-road.html)\n",
    "\n",
    "更多关于量化交易与机器学习相关请阅读[《机器学习之路》](http://www.abuquant.com/books/machine-learning-road.html)\n",
    "\n",
    "更多关于abu量化系统请关注微信公众号: abu_quant\n",
    "\n",
    "![](./image/qrcode.jpg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
